package com.itheima.reggie.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.Page;
import com.itheima.reggie.exception.BusinessException;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.DishFlavorMapper;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author: dw
 * @Date 2022/3/11 23:33
 */
@Service
public class DishServiceImpl implements DishService {

    @Autowired(required = false)
    private DishMapper dishMapper;

    @Autowired(required = false)
    private DishFlavorMapper dishFlavorMapper;

    @Autowired(required = false)
    private HttpSession session;

    @Autowired(required = false)
    private CategoryMapper categoryMapper;


    //注入缓存
    @Autowired(required = false)
    private RedisTemplate redisTemplate;

    /**
     * 条件分页查询
     *
     * @param page     当前页
     * @param pageSize 每页数据
     * @param name     按名称模糊查询
     * @return
     */
    /*@Override //分表查
    public Page<DishDto> findByPage(Integer page, Integer pageSize, String name) {
        //设置当前页和每页数据
        PageHelper.startPage(page,pageSize);
        //调用mapper查询
        List<Dish> dishList = dishMapper.findAll(name);
        //封装PageInfo
        PageInfo<Dish> pageInfo = new PageInfo<>(dishList);

        //将dishList的数据赋值给DishDtoList
        List<DishDto> dishDtoList = dishList.stream().map((dish -> {
            DishDto dishDto = new DishDto();
            //将dish的数据赋值给dishDto
            BeanUtils.copyProperties(dish,dishDto);

            //根据分类id查询分类
            Category category = categoryMapper.findById(dishDto.getCategoryId());
            //将分类对象中分类名称赋值给dishDto对象中
            dishDto.setCategoryName(dishDto.getName());

            return dishDto;
        })).collect(Collectors.toList());

        //再次封装成Page
        Page<DishDto> dishDtoPage = new Page<>();
        dishDtoPage.setRecords(dishDtoList);
        dishDtoPage.setTotal(pageInfo.getTotal());

        return dishDtoPage;
    }*/
    @Override  //连表查询
    public Page<DishDto> findByPage(Integer page, Integer pageSize, String name) {

        //设置当前页和每页数据
        PageHelper.startPage(page, pageSize);

        //调用mapper查询
        List<DishDto> dishDtoList = dishMapper.findAllByPage(name);
        //封装PageInfo
        PageInfo<DishDto> pageInfo = new PageInfo<>(dishDtoList);
        //封装Page
        Page<DishDto> dishDtoPage = new Page<>();
        dishDtoPage.setTotal(pageInfo.getTotal());
        dishDtoPage.setRecords(pageInfo.getList());

        return dishDtoPage;
    }

    /**
     * 添加菜品
     *
     * @param dishDto
     * @return
     */
    @Override
    @Transactional
    public boolean save(DishDto dishDto) {
        //判断该菜品有无重名
        Dish dish = dishMapper.findByName(dishDto);
        if (dish != null) {
            throw new BusinessException("该菜品名字已存在，请勿重复添加");
        }

        //获取会话域中id
        Long id = (Long) session.getAttribute("employee");
        //补全菜品数据
        dishDto.setCreateTime(LocalDateTime.now());
        dishDto.setUpdateTime(LocalDateTime.now());
        dishDto.setCreateUser(id);
        dishDto.setUpdateUser(id);
        dishDto.setSort(0);

        //调用mapper新增菜品
        dishMapper.save(dishDto);

        //补全口味列表
        List<DishFlavor> flavorList = dishDto.getFlavors().stream().map((dishFlavor -> {
            dishFlavor.setDishId(dishDto.getId());
            dishFlavor.setCreateTime(LocalDateTime.now());
            dishFlavor.setUpdateTime(LocalDateTime.now());
            dishFlavor.setCreateUser(id);
            dishFlavor.setUpdateUser(id);
            return dishFlavor;
        })).collect(Collectors.toList());

        //调用mapper新增菜品关联下的口味列表
        dishFlavorMapper.save(flavorList);

        //由于菜品的数据已经发生变化了，那么需要清空缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);
        return true;
    }

    /**
     * 根据id回显页面
     *
     * @param id
     * @return
     */
    @Override
    public DishDto findById(Long id) {
        DishDto dishDto = dishMapper.findById(id);
        return dishDto;
    }

    /**
     * 修改菜品
     *
     * @param dishDto
     * @return
     */
    @Override
    @Transactional
    public boolean update(DishDto dishDto) {
        //判断该菜品是否存在，排除自己比较
        Dish dish = dishMapper.findByName(dishDto);
        if (dish != null && !dish.getId().equals(dishDto.getId())) {
            throw new BusinessException("该菜品已存在，请重新输入");
        }

        //获取会话域中的id
        Long id = (Long) session.getAttribute("employee");
        //补全修改信息
        dishDto.setSort(0);
        dishDto.setUpdateTime(LocalDateTime.now());
        dishDto.setUpdateUser(id);

        //调用mapper修改菜品
        dishMapper.update(dishDto);

        //根据菜品id删除口味列表
        dishFlavorMapper.delete(dishDto.getId());

        //重新添加口味列表
        List<DishFlavor> dishFlavorList = dishDto.getFlavors().stream().map((dishFlavor -> {
            dishFlavor.setDishId(dishDto.getId());
            dishFlavor.setCreateTime(dishDto.getCreateTime());
            dishFlavor.setUpdateTime(dishDto.getUpdateTime());
            dishFlavor.setCreateUser(dishDto.getCreateUser());
            dishFlavor.setUpdateUser(dishDto.getUpdateUser());
            return dishFlavor;
        })).collect(Collectors.toList());

        //调用mapper插入口味列表
        dishFlavorMapper.save(dishFlavorList);


        //清理所有菜品的缓存数据
        Set keys = redisTemplate.keys("dish_*"); //获取所有以dish_xxx开头的key
        redisTemplate.delete(keys); //删除这些key

        return true;
    }

    /**
     * 批量修改状态
     *
     * @param status
     * @param ids
     */
    @Override
    public boolean updateStatus(Integer status, List<Long> ids) {
        dishMapper.updateStatus(status, ids);
        return true;
    }

    /**
     * 根据菜系id查询所有菜品（套餐用）
     *
     * @param categoryId
     * @return
     */
    /*@Override
    public List<Dish> findByCategoryId(Long categoryId) {
        return dishMapper.findByCategoryId(categoryId);
    }*/

    /**
     * 根据类别id和状态码查询所有菜品
     *
     * @param categoryId
     * @param status
     * @return
     */
    @Override
    public List<DishDto> findCategoryIdAndStatus(Long categoryId, Integer status) {
        //查询缓存类别的菜品列表，key="dish_"+categoryId+"_"+status;
        String key = "dish_" + categoryId + "_" + status;
        List<DishDto> dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);

        //查询到的数据为null，则调用数据库查询
        if (dishDtoList==null) {
            List<Dish> dishList = dishMapper.findCategoryIdAndStatus(categoryId, status);
            dishDtoList = dishList.stream().map((dish -> {
                DishDto dishDto = new DishDto();

                //将dish的属性封装到dishDto中
                BeanUtils.copyProperties(dish, dishDto);

                //根据菜品id获取口味列表并封装到dto对象中
                List<DishFlavor> dishFlavorList = dishFlavorMapper.findByDishId(dishDto.getId());
                dishDto.setFlavors(dishFlavorList);

                return dishDto;
            })).collect(Collectors.toList());

            //将数据库查到的对象写入缓存中
            redisTemplate.opsForValue().set(key,dishDtoList,600, TimeUnit.SECONDS);
        }
        return dishDtoList;
    }
}
